package com.maiji.cloud.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.common.collect.Lists;
import com.maiji.cloud.config.MyRedisConfig;
import com.maiji.cloud.entities.login.*;
import com.maiji.cloud.mapper.RecipeMapper;
import com.maiji.cloud.request.ReqMetaData;
import com.maiji.cloud.request.login.RecipeReqData;
import com.maiji.cloud.request.login.RecipeFindAllReqData;
import com.maiji.cloud.response.*;
import com.maiji.cloud.response.login.RecipeData;
import com.maiji.cloud.response.login.RecipeResData;
import com.maiji.cloud.response.login.UploadImageResData;
import com.maiji.cloud.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.maiji.cloud.utils.*;
import org.apache.poi.ss.usermodel.*;
import org.dom4j.*;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class RecipeServiceImpl extends ServiceImpl<RecipeMapper, Recipe> implements RecipeService {

    @Autowired
    private RedisTemplate<String, Object> maiji1RedisTemplate;
    @Autowired
    private AppUserService appUserService;
    @Autowired
    private UploadRecordService uploadRecordService;
    @Autowired
    private LabelMiddleRecipeService labelMiddleRecipeService;
    @Autowired
    private RecipeService recipeService;
    @Autowired
    private RecipeMapper recipeMapper;
    @Autowired
    private AreaInfoService areaInfoService;
    @Autowired
    private LabelService labelService;
    @Autowired
    private RecipeThumbsUpOrCollectionService recipeTOCService;
    @Autowired
    private RecipeIngredientService recipeIngredientService;
    @Autowired
    private FoodMaterialService foodMaterialService;
    @Autowired
    private UserService userService;

    @Override
    public BaseMetaResDto<List<RecipeResData>> findAllRecommendRecipes(String token, ReqMetaData metaData) {
        Label label = labelService.findLabelBySourceName("食谱", "美食推荐");
        if (label == null) return new BaseMetaResDto<>(Status.ERROR.setMessage("未查询到“食谱-美食”推荐标签"));
        List<String> selectedRecipeIds = labelMiddleRecipeService.selectList(new EntityWrapper<LabelMiddleRecipe>().eq("label_id", label.getUuId()))
                .parallelStream().map(LabelMiddleRecipe::getRecipeId).collect(Collectors.toList());
        List<RecipeResData> selectedRecipeList = Lists.newArrayList();
        if (selectedRecipeIds.size() > 0) selectedRecipeList = selectBatchIds(selectedRecipeIds).parallelStream().map(recipe -> {
            RecipeResData recipeResData = new RecipeResData();
            BeanUtils.copyProperties(recipe, recipeResData);
            return recipeResData.setIsRecommend(true);
        }).collect(Collectors.toList());
        List<Recipe> notSelectedRecipeList = selectList(new EntityWrapper<Recipe>().notIn("uu_id", selectedRecipeIds));
        List<RecipeData> allRecipeList = Lists.newArrayList();
        allRecipeList.addAll(selectedRecipeList);
        allRecipeList.addAll(notSelectedRecipeList);
        Integer pageNo = metaData.getPage();
        Integer pageSize = metaData.getSize();
        Integer fromIndex = (pageNo - 1) * pageSize;
        Integer total = allRecipeList.size();
        if (fromIndex >= total) return new BaseMetaResDto(Status.ERROR.setMessage("分页参数错误"));
        Integer toIndex = pageNo * pageSize;
        toIndex = toIndex < total ? toIndex : total;
        List<RecipeData> recipeList = allRecipeList.subList(fromIndex, toIndex);
        Long resMetaTotal = StringUtil.isBlank(token)? total.longValue(): selectedRecipeIds.size();
        ResMetaData resMetaData = new ResMetaData(pageNo, pageSize, resMetaTotal);
        return findAllRecipesWithToken(recipeList, token, resMetaData);
    }

    @Override
    public BaseMetaResDto<List<RecipeResData>> findAllRecipes(RecipeFindAllReqData data, String token, ReqMetaData metaData) {
        EntityWrapper<Recipe> entityWrapper = new EntityWrapper<>();
        List<String> labelIds = data.getLabelIds();
        if (labelIds != null && labelIds.size() > 0) {
            Wrapper<LabelMiddleRecipe> wrapper = new EntityWrapper<LabelMiddleRecipe>().in("label_id", labelIds);
            List<String> recipeIds = labelMiddleRecipeService.selectList(wrapper)
                    .stream().map(LabelMiddleRecipe::getRecipeId).collect(Collectors.toList());
            if (recipeIds.size() > 0) entityWrapper.in("uu_id", recipeIds);
        }
        if (StringUtil.isNotBlank(data.getName())) {
            entityWrapper.like("name", data.getName());
            entityWrapper.or();
            entityWrapper.like("alias", data.getName());
        }
        List<String> recipeIdList = data.getRecipeIds();
        if (recipeIdList != null && recipeIdList.size() > 0) entityWrapper.in("uu_id", recipeIdList);
        BaseService.dealWithEntityWrapper(entityWrapper, data.getCollectionNos(), "collection_no");
        BaseService.dealWithEntityWrapper(entityWrapper, data.getThumbsUpNos(), "thumbs_up_no");
        BaseService.dealWithEntityWrapper(entityWrapper, data.getLookUpNos(), "look_up_no");
        BaseService.dealWithEntityWrapper(entityWrapper, data.getUpdateTimes(), "update_time");
        BaseService.dealWithEntityWrapper(entityWrapper, data.getUploadTimes(), "upload_time");
        entityWrapper.orderBy(data.getOrderBy(), data.getOrder().equals("asc")? true: false);
        Page<Recipe> recipePage = selectPage(new Page<>(metaData.getPage(), metaData.getSize()), entityWrapper);
        ResMetaData resMetaData = new ResMetaData(recipePage.getCurrent(), recipePage.getSize(), recipePage.getTotal());
        return findAllRecipesWithToken(recipePage.getRecords(), token, resMetaData);
    }

    @Override
    public BaseMetaResDto<List<RecipeResData>> findAllRecipesByFoodId(String token, String foodId, ReqMetaData reqMetaData) {
        List<String> recipeIds = recipeIngredientService.selectList(new EntityWrapper<RecipeIngredient>().eq("food_id", foodId))
                .stream().map(RecipeIngredient::getRecipeId).collect(Collectors.toList());
        if (recipeIds.size() == 0) {
            ResMetaData resMetaData = new ResMetaData(reqMetaData.getPage(), reqMetaData.getSize(), 0L);
            return new BaseMetaResDto(Status.SUCCESS).setData(Lists.newArrayList()).setResMetaData(resMetaData);
        }
        RecipeFindAllReqData recipeFindAllReqData = new RecipeFindAllReqData().setRecipeIds(recipeIds);
        return findAllRecipes(recipeFindAllReqData, token, reqMetaData);
    }

    @Override
    public BaseResDto addOrCancelRecommend(String recipeId) {
        Label label = labelService.findLabelBySourceName("食谱", "美食推荐");
        if (label == null) return new BaseMetaResDto<>(Status.ERROR.setMessage("为查询到“食谱-美食”推荐标签"));
        Wrapper<LabelMiddleRecipe> wrapper = new EntityWrapper<LabelMiddleRecipe>()
                .eq("recipe_id", recipeId)
                .eq("label_id", label.getUuId());
        LabelMiddleRecipe labelMiddleRecipe = labelMiddleRecipeService.selectOne(wrapper);
        if (labelMiddleRecipe == null) {
            labelMiddleRecipe = new LabelMiddleRecipe()
                    .setUuId(UUID_MD5.getUUID())
                    .setRecipeId(recipeId)
                    .setLabelId(label.getUuId());
            if (! labelMiddleRecipeService.insert(labelMiddleRecipe)) return new BaseResDto(Status.ERROR.setMessage("添加美食推荐失败"));
        } else if (! labelMiddleRecipeService.deleteById(labelMiddleRecipe.getUuId())) return new BaseResDto(Status.ERROR.setMessage("取消美食推荐失败"));
        return new BaseResDto(Status.SUCCESS);
    }

    @Override
    public BaseMetaResDto<List<RecipeResData>> findAllRecipeByLogin(String token, ReqMetaData metaData) {
        AppUser appUser = RedisUtil.getAppUserByRedis(maiji1RedisTemplate, MyRedisConfig.REDISDATABASENO, token, appUserService);
        UserInfo userInfo = userService.selectOne(new EntityWrapper<UserInfo>().eq("user_id", appUser.getUuId()));
        AreaInfo areaInfo = areaInfoService.selectById(userInfo.getAreaId());
        Label provinceLabel = labelService.selectOne(new EntityWrapper<Label>().eq("name", areaInfo.getProvince()));
        List<String> provinceRecipeIds = labelMiddleRecipeService.selectList(new EntityWrapper<LabelMiddleRecipe>().eq("label_id", provinceLabel.getUuId()))
                .stream().map(LabelMiddleRecipe::getRecipeId).collect(Collectors.toList());
        String recommendLabelId = labelService.selectOne(new EntityWrapper<Label>().eq("name", "美食推荐")).getUuId();
        List<String> recommendRecipeIds = labelMiddleRecipeService.selectList(new EntityWrapper<LabelMiddleRecipe>().eq("label_id", recommendLabelId))
                .stream().map(LabelMiddleRecipe::getRecipeId).filter(id -> ! provinceRecipeIds.contains(id)).collect(Collectors.toList());
        Page<RecipeResData> page = new Page<>(metaData.getPage(), metaData.getSize());
        List<RecipeResData> recipeList = recipeMapper.findAllRecipeByLogin(provinceRecipeIds, recommendRecipeIds, page);
        if (recipeList.size() == 0) return new BaseMetaResDto<>(Status.ERROR);
        ResMetaData resMetaData = new ResMetaData(page.getCurrent(), page.getSize(), recipeList.size());
        return findAllRecipesWithToken(recipeList, token, resMetaData);
    }

    public <T> BaseMetaResDto<List<RecipeResData>> findAllRecipesWithToken(List<T> recipeList, String token, ResMetaData resMetaData) {
        List<String> recipeIds = recipeList.parallelStream().map(instance -> {
            try {
                Class<T> rClass = (Class<T>) instance.getClass();
                Method midMapKeyMethod = rClass.getDeclaredMethod("getUuId");
                return (String) midMapKeyMethod.invoke(instance);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }).collect(Collectors.toList());
        Wrapper<UploadRecord> wrapper = new EntityWrapper<UploadRecord>().in("belong_id", recipeIds).eq("is_main", 1);
        List<RecipeResData> recipeResDataList = BaseService.dealWithOneToOne(recipeList, "getUuId", RecipeResData.class,
                "setMainImage", uploadRecordService.selectList(wrapper), "getBelongId", UploadImageResData.class);
        if (StringUtil.isNotBlank(token)) {
            AppUser appUser = RedisUtil.getAppUserByRedis(maiji1RedisTemplate, MyRedisConfig.REDISDATABASENO, token, appUserService);
            recipeResDataList.parallelStream().forEach(recipe -> {
                if (recipe.getAlias() != null) recipe.setAliases(Arrays.asList(recipe.getAlias().split("，")));
                recipe.setIsThumbsUp((recipeTOCService.isThumbsUpOrCollection(recipe.getUuId(), appUser.getUuId(), 1)));
                recipe.setIsCollection((recipeTOCService.isThumbsUpOrCollection(recipe.getUuId(), appUser.getUuId(), 2)));
            });
        }
        return new BaseMetaResDto<List<RecipeResData>>(Status.SUCCESS).setData(recipeResDataList).setResMetaData(resMetaData);
    }

    @Override
    public BaseDataResDto<RecipeResData> findRecipeById(String recipeId, String token) {
        String redisKey = RedisUtil.getRedisKey(REDISNAMESPACE, recipeId);
        RecipeResData recipe = (RecipeResData) maiji1RedisTemplate.opsForValue().get(redisKey);
        if (recipe == null) {
            Wrapper<UploadRecord> wrapper = new EntityWrapper<UploadRecord>().eq("belong_id", recipeId).eq("is_main", 1);
            recipe = BaseService.dealWithOneToOne(Arrays.asList(selectById(recipeId)), "getUuId", RecipeResData.class,
                "setMainImage", uploadRecordService.selectList(wrapper), "getBelongId", UploadImageResData.class).get(0);
            if (recipe != null) RedisUtil.setObject(maiji1RedisTemplate, redisKey, recipe);
            else return new BaseDataResDto<>(Status.PARAMETERERROR);
        }
        if (recipe.getAlias() != null) recipe.setAliases(Arrays.asList(recipe.getAlias().split("、")));
        List<RecipeIngredient> ingredients = recipeIngredientService.selectList(new EntityWrapper<RecipeIngredient>().eq("recipe_id", recipeId));
        Map<Boolean, List<RecipeIngredient>> recipeIngredients = ingredients.stream().collect(Collectors.groupingBy(RecipeIngredient::getMain));
        recipe.setMainFoods(recipeIngredients.get(true)).setFoods(recipeIngredients.get(false));
        recipe.setFoodIds(ingredients.stream().map(RecipeIngredient::getFoodId).collect(Collectors.toList()));
        if (StringUtil.isNotBlank(token)) {
            AppUser appUser = RedisUtil.getAppUserByRedis(maiji1RedisTemplate, MyRedisConfig.REDISDATABASENO, token, appUserService);
            recipe.setIsThumbsUp((recipeTOCService.isThumbsUpOrCollection(recipe.getUuId(), appUser.getUuId(), 1)));
            recipe.setIsCollection((recipeTOCService.isThumbsUpOrCollection(recipe.getUuId(), appUser.getUuId(), 2)));
        }
        return new BaseDataResDto<RecipeResData>(Status.SUCCESS).setData(recipe);
    }

    @Override
    public BaseDataResDto<List<Label>> findAllLabelsByRecipeId(String recipeId) {
        EntityWrapper<LabelMiddleRecipe> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("recipe_id", recipeId);
        List<String> labelIds = labelMiddleRecipeService.selectList(entityWrapper).stream()
                .map(LabelMiddleRecipe::getLabelId).collect(Collectors.toList());
        if (labelIds.size() == 0) return new BaseDataResDto<>(Status.ERROR);
        List<Label> labels = labelService.selectBatchIds(labelIds);
        return new BaseDataResDto<List<Label>>(Status.SUCCESS).setData(labels);
    }

    @Override
    public BaseResDto delRecipesByIds(List<String> recipeIds) {
        if (! deleteBatchIds(recipeIds)) return new BaseResDto(Status.ERROR);
        return new BaseResDto(Status.SUCCESS);
    }

    @Override
    public BaseResDto addRecipe(RecipeReqData data) throws Exception {
        String recipeId = UUID_MD5.getUUID();
        Recipe recipe = new Recipe().setUuId(recipeId)
                .setName(data.getName())
                .setAlias(data.getAlias())
                .setNote(data.getNote())
                .setUploadTime(new Date());
        List<UploadRecord> uploadRecords = Lists.newArrayList();
        String detailsText = DetailTextUtil.dealDetailText(MaijiOSS.OSSRECIPEBUKET, recipeId, data.getDetailsText(), uploadRecords);
        List<RecipeIngredient> recipeIngredients = data.getFoods().stream().map(RecipeIngredient ->
                RecipeIngredient.setUuId(UUID_MD5.getUUID()).setRecipeId(recipeId)).collect(Collectors.toList());
        List<LabelMiddleRecipe> labelMiddleRecipes = data.getLabels().stream().map(label ->
                label.setUuId(UUID_MD5.getUUID()).setRecipeId(recipeId)).collect(Collectors.toList());
        if (insert(recipe.setDetailsText(detailsText)) && recipeIngredientService.insertBatch(recipeIngredients) &&
                labelMiddleRecipeService.insertBatch(labelMiddleRecipes) && uploadRecordService.insertBatch(uploadRecords)&&
                uploadRecordService.updateById(new UploadRecord().setUuId(data.getMainImageId()).setBelongId(recipeId).setIsMain(1)) )
            return new BaseResDto(Status.SUCCESS);
        return new BaseResDto(Status.ERROR);
    }

    @Override
    public BaseResDto editRecipe(RecipeReqData data) throws Exception {
        String recipeId = data.getUuId();
        if (StringUtil.isBlank(recipeId)) return new BaseResDto(Status.ERROR);
        String mainImageId = data.getMainImageId();
        EntityWrapper<UploadRecord> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("belong_id", recipeId);
        entityWrapper.eq("is_main", 1);
        UploadRecord uploadRecord = uploadRecordService.selectOne(entityWrapper);
        if (! uploadRecord.getUuId().equals(mainImageId)) {
            List<UploadRecord> uploadRecords = Lists.newArrayList();
            uploadRecords.add(uploadRecord.setBelongId(""));
            uploadRecords.add(new UploadRecord().setUuId(mainImageId).setBelongId(recipeId).setIsMain(1));
            if (! uploadRecordService.updateBatchById(uploadRecords)) return new BaseResDto(Status.ERROR);
        }
        recipeIngredientService.delete(new EntityWrapper<RecipeIngredient>().eq("recipe_id", recipeId));
        List<RecipeIngredient> foods= data.getFoods().stream().map(food -> {
            if (StringUtil.isBlank(food.getUuId())) food.setUuId(UUID_MD5.getUUID()).setRecipeId(recipeId);
            return food;
        }).collect(Collectors.toList());
        if (foods.size() > 0) if (! recipeIngredientService.insertBatch(foods)) return new BaseResDto(Status.ERROR);
        List<UploadRecord> uploadRecords = Lists.newArrayList();
        String detailsText = DetailTextUtil.dealDetailText(MaijiOSS.OSSRECIPEBUKET, recipeId, data.getDetailsText(), uploadRecords);
        if (uploadRecords.size() > 0 && ! uploadRecordService.insertBatch(uploadRecords)) return new BaseResDto(Status.ERROR);
        List<LabelMiddleRecipe> labels = data.getLabels();
        Wrapper<LabelMiddleRecipe> wrapper = new EntityWrapper<LabelMiddleRecipe>().eq("recipe_id", recipeId);
        if (! labelMiddleRecipeService.delete(wrapper)) return new BaseResDto(Status.ERROR.setMessage("编辑食谱标签失败"));
        labels= labels.parallelStream().map(label -> label.setUuId(UUID_MD5.getUUID()).setRecipeId(recipeId)).collect(Collectors.toList());
        if (! labelMiddleRecipeService.insertBatch(labels)) return new BaseResDto(Status.ERROR.setMessage("编辑食谱标签失败"));
        Recipe recipe = new Recipe();
        BeanUtils.copyProperties(data, recipe);
        recipe.setDetailsText(detailsText).setUpdateTime(new Date());
        if (! updateById(recipe)) return new BaseResDto(Status.ERROR);
        maiji1RedisTemplate.delete(RedisUtil.getRedisKey(REDISNAMESPACE, recipeId));
        return new BaseResDto(Status.SUCCESS);
    }

    @Override
    public BaseDataResDto<String> uploadRecipes(MultipartFile uploadFile) throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        List<Recipe> recipes = Lists.newArrayList();
        List<LabelMiddleRecipe> labelMiddleRecipes = Lists.newArrayList();
        List<RecipeIngredient> recipeIngredients = Lists.newArrayList();
        List<UploadRecord> uploadRecords = Lists.newArrayList();
        Workbook workbook = WorkbookFactory.create(uploadFile.getInputStream());
        StringBuffer errorTxt = new StringBuffer();
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            Sheet sheet = workbook.getSheetAt(i);
            for (int j = 0; j <= sheet.getPhysicalNumberOfRows(); j++) {
                if (j == 0) {  //标题行
                    errorTxt.append("错误行号\t错误信息提示\r\n");
                    continue;
                }
                Row row = sheet.getRow(j);
                if (row == null) continue;  //没数据
                String recipeId = UUID_MD5.getUUID();
                Recipe recipe = new Recipe().setUuId(recipeId);
                Boolean flag = true;
                rowFor: for (int k = 0; k < 8; k++) {
                    String cellValue =  row.getCell(k)!=null? row.getCell(k).getStringCellValue(): null;
                    switch (k) {
                        case 0:
                            if (StringUtil.isBlank(cellValue)) {
                                errorTxt.append(j+1+ "\t\t\t食谱名称不可为空\r\n");
                                flag = false;
                                break rowFor;
                            }
                            Recipe selectOne = selectOne(new EntityWrapper<Recipe>().eq("name", cellValue));
                            if (selectOne != null) {
                                flag = false;
                                break rowFor;
                            }
                            recipe.setName(cellValue);
                            break;
                        case 1:
                            if (StringUtil.isNotBlank(cellValue)) recipe.setAlias(cellValue);
                            break;
                        case 2:
                            if (StringUtil.isBlank(cellValue)) {
                                errorTxt.append(j+1+ "\t\t\t食谱主料不可为空\r\n");
                                flag = false;
                                break rowFor;
                            }
                            String[] mainFoodRecords = cellValue.split("、");
                            for (String mainFoodRecord: Arrays.asList(mainFoodRecords)) {
                                String[] mainFoodStrs = mainFoodRecord.split("/");
                                Wrapper<FoodMaterialEntity> wrapper = new EntityWrapper<FoodMaterialEntity>()
                                        .eq("name", mainFoodStrs[0])
                                        .or()
                                        .like("alias", "、" + mainFoodStrs[0] + "、");
                                FoodMaterialEntity mainFood = foodMaterialService.selectOne(wrapper);
                                if (mainFood == null) {
                                    errorTxt.append(j+1+ "\t\t\t食谱主料“" + mainFoodStrs[0] + "”未在食材库中检索到\r\n");
                                    flag = false;
                                    break rowFor;
                                }
                                RecipeIngredient recipeIngredient = new RecipeIngredient()
                                        .setUuId(UUID_MD5.getUUID())
                                        .setFoodName(mainFood.getName())
                                        .setFoodId(mainFood.getUuId())
                                        .setRecipeId(recipeId)
                                        .setCascaderStr(mainFood.getCascaderStr() + "," + mainFood.getUuId())
                                        .setMain(true);
                                if (mainFoodStrs.length == 2) recipeIngredient.setConsumption(mainFoodStrs[1]);
                                recipeIngredients.add(recipeIngredient);
                            }
                            break;
                        case 3:
                            if (StringUtil.isNotBlank(cellValue)) {
                                String[] foodRecords = cellValue.split("、");
                                for (String foodRecord: Arrays.asList(foodRecords)) {
                                    String[] foodStrs = foodRecord.split("/");
                                    Wrapper<FoodMaterialEntity> wrapper = new EntityWrapper<FoodMaterialEntity>()
                                            .eq("name", foodStrs[0])
                                            .or()
                                            .like("alias", "、" + foodStrs[0] + "、");
                                    FoodMaterialEntity food = foodMaterialService.selectOne(wrapper);
                                    if (food == null) {
                                        errorTxt.append(j+1+ "\t\t\t食谱配料“" + foodStrs[0] + "”未在食材库中检索到\r\n");
                                        flag = false;
                                        break rowFor;
                                    }
                                    RecipeIngredient recipeIngredient = new RecipeIngredient()
                                            .setUuId(UUID_MD5.getUUID())
                                            .setFoodName(food.getName())
                                            .setFoodId(food.getUuId())
                                            .setRecipeId(recipeId)
                                            .setCascaderStr(food.getCascaderStr() + "," + food.getUuId())
                                            .setMain(false);
                                    if (foodStrs.length == 2) recipeIngredient.setConsumption(foodStrs[1]);
                                    recipeIngredients.add(recipeIngredient);
                                }
                            }
                            break;
                        case 4:
                            if (StringUtil.isNotBlank(cellValue)) {
                                String[] provinces = cellValue.split("、");
                                for (String province: Arrays.asList(provinces)) {
                                    Label provinceLabel = labelService.selectOne(new EntityWrapper<Label>().eq("name", province));
                                    if (provinceLabel == null) {
                                        errorTxt.append(j+1+ "\t\t\t食谱所属省份“" + province + "”填写错误\r\n");
                                        flag = false;
                                        break rowFor;
                                    }
                                    labelMiddleRecipes.add(new LabelMiddleRecipe()
                                        .setUuId(UUID_MD5.getUUID())
                                        .setLabelId(provinceLabel.getUuId())
                                        .setRecipeId(recipeId));
                                }
                            }
                            break;
                        case 5:
                            if (StringUtil.isBlank(cellValue)) {
                                errorTxt.append(j+1+ "\t\t\t食谱阶段标签ID不可为空\r\n");
                                flag = false;
                                break rowFor;
                            }
                            labelMiddleRecipes.add(new LabelMiddleRecipe()
                                    .setUuId(UUID_MD5.getUUID())
                                    .setLabelId(cellValue)
                                    .setRecipeId(recipeId));
                            break;
                        case 6:
                            if (StringUtil.isBlank(cellValue)) {
                                errorTxt.append(j+1+ "\t\t\t食谱详情图片不可为空\r\n");
                                flag = false;
                                break rowFor;
                            }
                            Document document = DocumentHelper.parseText("<div>" + cellValue + "</div>");
                            Element rootElement = document.getRootElement();
                            Iterator iterator = rootElement.elementIterator();
                            Integer no = -1;
                            StringBuilder detailsText = new StringBuilder();
                            while (iterator.hasNext()) {
                                Element p = (Element) iterator.next();
                                Element img = p.element("img");
                                String detailImgUrl = img.attributeValue("src");
                                String bucketName = "maiji-recipe-images";
                                String objName = UUID_MD5.getUUID() + ".jpg";
                                ResponseEntity<Resource> entity = new RestTemplate().postForEntity(new URI(detailImgUrl), null, Resource.class);
                                InputStream inputStream = entity.getBody().getInputStream();
                                MaijiOSS.aliyunOSSUpload2(bucketName, objName, inputStream);
                                uploadRecords.add(new UploadRecord()
                                        .setUuId(UUID_MD5.getUUID())
                                        .setBelongId(recipeId)
                                        .setUploadUserId("admin-1234567890")
                                        .setFileName(objName)
                                        .setUrl("https://" + bucketName + ".oss-cn-beijing.aliyuncs.com/" + objName)
                                        .setUploadTime(new Date())
                                        .setIsMain(0).setNo(++no));
                                detailsText.append("<p><img src=\"https://" + bucketName + ".oss-cn-beijing.aliyuncs.com/" + objName+ "\"/></p>");
                            }
                            recipe.setDetailsText(detailsText.toString());
                            break;
                        case 7:
                            if (StringUtil.isBlank(cellValue)) {
                                errorTxt.append(j+1+ "\t\t\t食谱主图不可为空\r\n");
                                flag = false;
                                break rowFor;
                            }
                            String bucketName = "maiji-recipe-images";
                            String objName = UUID_MD5.getUUID() + ".jpg";
                            ResponseEntity<Resource> entity = new RestTemplate().postForEntity(new URI(cellValue), null, Resource.class);
                            InputStream inputStream = entity.getBody().getInputStream();
                            MaijiOSS.aliyunOSSUpload2(bucketName, objName, inputStream);
                            uploadRecords.add(new UploadRecord()
                                    .setUuId(UUID_MD5.getUUID())
                                    .setBelongId(recipeId)
                                    .setUploadUserId("admin-1234567890")
                                    .setFileName(objName)
                                    .setUrl("https://" + bucketName + ".oss-cn-beijing.aliyuncs.com/" + objName)
                                    .setUploadTime(new Date())
                                    .setIsMain(1));
                            break;
                    }
                }
                if (flag) recipes.add(recipe.setUploadTime(new Date()));
            }
        }
        if (recipes.size() != 0) if (! recipeService.insertBatch(recipes)) return new BaseDataResDto(Status.ERROR);
        if (recipeIngredients.size() != 0) if (! recipeIngredientService.insertBatch(recipeIngredients)) return new BaseDataResDto(Status.ERROR);
        if (labelMiddleRecipes.size() != 0) if (! labelMiddleRecipeService.insertBatch(labelMiddleRecipes)) return new BaseDataResDto(Status.ERROR);
        if (uploadRecords.size() != 0) if (! uploadRecordService.insertBatch(uploadRecords)) return new BaseDataResDto(Status.ERROR);
        if (errorTxt.toString().length() > 13) return new BaseDataResDto<String>(Status.SUCCESS).setData(errorTxt.toString());
        return new BaseDataResDto(Status.SUCCESS);
    }

}
